<template>
  <n-data-table
    :columns="columns"
    :data="list"
    @update:sorter="handleSorterChange"
  ></n-data-table>
  <n-pagination
    v-if="pagination.itemCount"
    style="margin: 2em 0"
    v-model:page="pagination.page"
    v-model:page-size="pagination.pageSize"
    :page-count="pagination.itemCount"
    show-size-picker
    :page-sizes="pagination.pageSizes"
    @update:page="pagination.onChange"
    @update:page-size="pagination.onUpdatePageSize"
  />
</template>

<script lang="ts" setup>
import {
  NDataTable,
  NButton,
  NPopconfirm,
  NPagination,
  NTag,
  useMessage,
} from "naive-ui";
import { useRouter } from "vue-router";

import { usePageList, useModel, useData } from "@/api/CRUD";
import { statusName, replaceName } from "@/data";
import { ref, h, reactive } from "vue";

const message = useMessage();
const router = useRouter();

// 接收属性
const props = defineProps<{
  resource: string;
}>();

// 表格数据
const { list, total, getPageList } = usePageList(props.resource);
// 模型
const { model, getModel } = useModel(props.resource);
// 数据操作方法
const { remove } = useData(props.resource);
// 分页数据
const pagination = reactive({
  page: 1,
  pageSize: 5,
  pageSizes: [3, 5, 7],
  itemCount: 0,
  onChange: async (page: number) => {
    await getPageList(pagination.pageSize, page, order.order, order.sortName);
  },
  onUpdatePageSize: async (pageSize: number) => {
    await getPageList(pageSize, pagination.page, order.order, order.sortName);
    pagination.pageSize = pageSize;
    pagination.itemCount = Math.ceil(total.value / pagination.pageSize);
  },
});

const order = reactive({
  order: "desc",
  sortName: "updated_at",
});

function formatName(name: string) {
  if (name == "ID") return "id";
  let arr = Array.from(name);
  let top = arr.shift();
  let index = arr.findIndex((i) => i > "A" && i < "Z");
  if (~index) {
    arr.splice(index, 0, "_");
  }
  return [top, ...arr].join("").toLowerCase();
}

async function handleSorterChange(sorter: any) {
  order.sortName = formatName(sorter["columnKey"]);
  switch (sorter["order"]) {
    case "descend":
      order.order = "desc";
      break;
    case "ascend":
      order.order = "asc";
      break;
    default:
      order.order = "decs";
      order.sortName = "updated_at";
      break;
  }
  await getPageList(
    pagination.pageSize,
    pagination.page,
    order.order,
    order.sortName
  );
}

// 表标题
const columns = ref<any[]>();

// 修改按钮
function editButton(row: any) {
  return h(
    NButton,
    {
      strong: true,
      tertiary: true,
      size: "small",
      onClick: () => router.push(`/${props.resource}/edit/${row.ID}`),
    },
    { default: () => "修改" }
  );
}
// 删除按钮
function removeButton(row: any) {
  return h(
    NPopconfirm,
    {
      onPositiveClick: () => {
        removeById(row.ID);
      },
    },
    {
      trigger() {
        return h(
          NButton,
          {
            strong: true,
            tertiary: true,
            size: "small",
          },
          {
            default: () => "删除",
          }
        );
      },
      default: () => "确认删除?",
    }
  );
}

// 删除方法
async function removeById(id: string) {
  const msg = await remove(id);
  message.success(msg);
  await getPageList(pagination.pageSize);
}

// 创建生命周期
(async () => {
  // 请求必要的数据
  await getPageList(pagination.pageSize, pagination.page);
  pagination.itemCount = Math.ceil(total.value / pagination.pageSize);
  await getModel();

  // 根据请求数据生成表标题
  columns.value = Object.keys(Object(model.value)).map((k) => {
    function render(row: any) {
      // 渲染为标签
      if (k == "Status") {
        let type: any = "info";
        switch (row.Status) {
          case 1:
            type = "info";
            break;
          case 2:
            type = "warning";
            break;
          case 3:
            type = "success";
            break;
        }
        return h(
          NTag,
          {
            type,
          },
          {
            default: () => statusName[row[k]],
          }
        );
      }
      // 渲染省略
      if (k == "About") {
        return "……";
      }
      //正常渲染
      return row[k];
    }

    let sorter = true;
    if (k == "About") {
      sorter = false;
    }

    return {
      title: replaceName(k),
      key: k,
      ellipsis: true,
      render,
      sorter,
    };
  });
  columns.value.push({
    title: "操作",
    key: "options",
    render(row: any) {
      return h(
        "div",
        {
          class: "options",
        },
        [editButton(row), removeButton(row)]
      );
    },
  });
})();
</script>

<style>
.options {
  max-width: 8em;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1em;
}
</style>
